apply the configured number-length limit on the parse path - #95
Merged
Conversation
XmlOptions.setMaxNumberOfCharsForNumbers only reached MathUtil from Validator, ie only when XmlObject.validate(options) was called explicitly. The path that runs on every parse - lazy value materialization through XmlObjectBase.check_dated -> update_from_wscanon_text -> set_text - always used DEFAULT_MAX_NUMBER_CHARS, because no XmlOptions is reachable from a value holder. Raising or lowering the option had no effect there. Carry the limit on the Locale, the way _loadStrictFloatingPoint and _loadAllowDecimalExponent are already carried: a default method on XmlLocale, a field copied from the options in the Locale constructor, and a get_max_number_chars() helper on XmlObjectBase for the holders to use. Add the maxNumberOfChars overloads that were missing, so there is something to pass the value to: MathUtil.parseAsBigInteger, parseAsLong and toBigInteger, and XsTypeConverter.lexDecimal, lexInteger and lexLong. lexInt/lexShort/lexByte need none - they use the hand-rolled parseIntXsdNumber and are bounded by the target type. Wire it through the decimal, integer and long holders. Every new overload is additive and the existing signatures keep defaulting to DEFAULT_MAX_NUMBER_CHARS, so behaviour is unchanged unless the option is set. Validator needs no change: integer-derived types route through its BTC_DECIMAL case, which is already wired. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-on to #94.
XmlOptions.setMaxNumberOfCharsForNumbersis currently honoured in only one place.The gap
The configured value reaches
MathUtilfrom exactly one production caller —Validator— so it applies only when someone callsXmlObject.validate(options)explicitly. The path that runs on everyparse()is lazy value materialization,XmlObjectBase.check_dated→update_from_wscanon_text→set_textin the value holders, and that always usedDEFAULT_MAX_NUMBER_CHARS, because noXmlOptionsis reachable from a value holder. Raising or lowering the option had no effect there. SeveralMathUtilandXsTypeConvertermethods also had nomaxNumberOfCharsoverload at all, so there was nothing to pass the value to even where it was in scope.Approach
Carry the limit on the
Locale, exactly as_loadStrictFloatingPointand_loadAllowDecimalExponentare already carried: a default method onXmlLocale, a field copied from the options in theLocaleconstructor, and aget_max_number_chars()helper onXmlObjectBaseso the holders have one place to read it. Two lines of this idiom were already present atJavaDecimalHolder:46andJavaFloatHolder:55.Add the missing overloads so there is something to pass the value to —
MathUtil.parseAsBigInteger,parseAsLong,toBigInteger, andXsTypeConverter.lexDecimal,lexInteger,lexLong.lexInt/lexShort/lexByteneed none: they use the hand-rolledparseIntXsdNumber/parseShort/parseByte, are bounded by the target type, and never callMathUtil.Wire it through the decimal, integer and long holders, and through
XmlObjectBase.getBigIntegerValue().Validatorneeds no change — all integer-derived types route through itsBTC_DECIMALcase (note thederivedFromInteger(type)check), which is already wired.Compatibility
Every new overload is additive, and every existing signature keeps defaulting to
DEFAULT_MAX_NUMBER_CHARS. Nothing changes for callers who do not set the option. Callers who do set it get the behaviour the setter has always advertised — worth noting as a behaviour change for anyone who set it and, without knowing it, got no effect on the parse path.New
@sincetags are 5.4.1, since 5.4.0 is released.Not in scope
GDate/GDurationfractional seconds — the constructors are public API with no options in scope, so wiring them means new public API on two widely-used classes. Still bounded by the 1024 default.XMLStreamReaderExtImpl(rich parser) is built from a bareXMLStreamReaderwith no options; it can pick up the new overloads later.PrettyPrinter,Inst2Xsd,SampleXmlUtil,StscTranslator,SchemaTypeLoaderBase,SOAPArrayType,XmlCalendar,XPathFactory,QNameCache) — trusted or hardcoded input.Verification
MaxNumberOfCharsTestparses a 2000-character number and materializes it. With the main-source changes reverted, its 4 configured-limit tests fail and its 3 default-behaviour tests pass — which is exactly the intended split: the option starts working, and unset behaviour is untouched.Ran
misc.checkin.*,impl.util.*and thevaluestests locally — 112 pass. Leaving the full suite to CI.🤖 Generated with Claude Code